REPO_ROOT := `realpath ..`  # path to the root of the optimism monorepo
KURTOSIS_DIR := REPO_ROOT + "/kurtosis-devnet"
ACCEPTOR_VERSION := env_var_or_default("ACCEPTOR_VERSION", "v3.8.0")
DOCKER_REGISTRY := env_var_or_default("DOCKER_REGISTRY", "us-docker.pkg.dev/oplabs-tools-artifacts/images")
ACCEPTOR_IMAGE := env_var_or_default("ACCEPTOR_IMAGE", DOCKER_REGISTRY + "/op-acceptor:" + ACCEPTOR_VERSION)

# Default recipe - runs acceptance tests
default:
    @just acceptance-test "" base

jovian:
    @just acceptance-test jovian jovian

interop:
    @just acceptance-test "" interop

cgt:
    @just acceptance-test "" cgt


# Run acceptance tests with mise-managed binary
# Usage: just acceptance-test [devnet] [gate]
# Examples:
#   just acceptance-test "" base         # In-process (sysgo) with specific gate
#   just acceptance-test "" ""           # In-process gateless mode (all tests)
#   just acceptance-test "simple" base     # External devnet with specific gate
#   just acceptance-test "simple" ""       # External devnet gateless mode (all tests)
acceptance-test devnet="" gate="base":
    #!/usr/bin/env bash
    set -euo pipefail

    # Determine mode and orchestrator
    GATELESS_MODE=$([[ "{{gate}}" == "" ]] && echo "true" || echo "false")
    ORCHESTRATOR=$([[ "{{devnet}}" == "" ]] && echo "sysgo" || echo "sysext")

    # Display mode information
    if [[ "$GATELESS_MODE" == "true" ]]; then
        echo -e "DEVNET: $([[ "$ORCHESTRATOR" == "sysgo" ]] && echo "in-memory" || echo "{{devnet}}") ($ORCHESTRATOR), MODE: gateless (all tests)\n"
    else
        echo -e "DEVNET: $([[ "$ORCHESTRATOR" == "sysgo" ]] && echo "in-memory" || echo "{{devnet}}") ($ORCHESTRATOR), GATE: {{gate}}\n"
    fi

    # Build dependencies for sysgo (in-process) mode if not in CI
    # In CI jobs already take care of this, so we skip it.
    if [[ "$ORCHESTRATOR" == "sysgo" && -z "${CIRCLECI:-}" ]]; then
        echo "Building contracts (local build)..."
        cd {{REPO_ROOT}}
        echo " - Updating submodules..."
        git submodule update --init --recursive
        echo " - Installing mise..."
        mise install
        cd packages/contracts-bedrock
        echo " - Installing contracts..."
        just install
        echo " - Forge build..."
        just build-no-tests
        cd {{REPO_ROOT}}

        echo "Checking cannon dependencies..."
        if [ ! -e {{REPO_ROOT}}/cannon/bin/cannon ] || [ ! -e {{REPO_ROOT}}/op-program/bin/prestate-mt64.bin.gz ]; then
            echo "Building cannon dependencies..."
            cd {{REPO_ROOT}}
            make cannon-prestates
        fi
    fi

    cd {{REPO_ROOT}}/op-acceptance-tests

    # Check mise installation and fallback to Docker if needed
    if ! command -v mise >/dev/null; then
        echo "Mise not installed, falling back to Docker..."
        just acceptance-test-docker {{devnet}} {{gate}}
        exit 0
    fi

    # Install op-acceptor using mise
    if ! mise install op-acceptor; then
        echo "WARNING: Failed to install op-acceptor with mise, falling back to Docker..."
        just acceptance-test-docker {{devnet}} {{gate}}
        exit 0
    fi

    # Set binary path and log level
    BINARY_PATH=$(mise which op-acceptor)
    echo "Using mise-managed binary: $BINARY_PATH"
    LOG_LEVEL="$(echo "${LOG_LEVEL:-info}" | grep -E '^(debug|info|warn|error)$' || echo 'info')"
    echo "LOG_LEVEL: $LOG_LEVEL"

    # Deploy devnet for sysext if it's a simple name
    if [[ "$ORCHESTRATOR" == "sysext" && ! "{{devnet}}" =~ ^(kt://|ktnative://|/) ]]; then
        echo "Deploying devnet {{devnet}}..."
        just {{KURTOSIS_DIR}}/{{devnet}}-devnet || true
    fi

    # Build command arguments based on mode
    if [[ "$GATELESS_MODE" == "true" ]]; then
        # Gateless mode - use binary directly
        CMD_ARGS=(
            "$BINARY_PATH"
            "--testdir" "{{REPO_ROOT}}/op-acceptance-tests/..."
            "--validators" "./acceptance-tests.yaml"
            "--exclude-gates" "flake-shake"
            "--allow-skips"
            "--timeout" "120m"
            "--orchestrator" "$ORCHESTRATOR"
            "--show-progress"
        )
    else
        # Gate mode - use go run with acceptor binary
        CMD_ARGS=(
            "go" "run" "cmd/main.go"
            "--gate" "{{gate}}"
            "--testdir" "{{REPO_ROOT}}"
            "--validators" "./acceptance-tests.yaml"
            "--acceptor" "$BINARY_PATH"
            "--log.level" "${LOG_LEVEL}"
            "--orchestrator" "$ORCHESTRATOR"
            "--show-progress"
        )
    fi

    # Add sysext-specific arguments
    if [[ "$ORCHESTRATOR" == "sysext" ]]; then
        CMD_ARGS+=("--devnet" "{{devnet}}" "--kurtosis-dir" "{{KURTOSIS_DIR}}" "--serial")
    fi

    # Execute the command
    "${CMD_ARGS[@]}"



# Run acceptance tests against a devnet using Docker (fallback if needed)
acceptance-test-docker devnet="simple" gate="base":
    #!/usr/bin/env bash
    set -euo pipefail

    echo -e "DEVNET: {{devnet}}, GATE: {{gate}}\n"

    # First run the appropriate devnet from the kurtosis-devnet directory if needed.
    just {{KURTOSIS_DIR}}/{{ devnet }}-devnet

    # Print which image is being used (for debugging)
    echo "Using acceptor image: {{ACCEPTOR_IMAGE}}"

    # Run op-acceptor with the repository mounted at the correct Go module path
    docker run \
        -v "$(pwd)/acceptance-tests.yaml:/acceptance-tests.yaml" \
        -v "{{REPO_ROOT}}:/go/src/github.com/ethereum-optimism/optimism" \
        {{ACCEPTOR_IMAGE}} \
        --testdir "/go/src/github.com/ethereum-optimism/optimism" \
        --gate {{gate}} \
        --validators /acceptance-tests.yaml \
        $( [[ "{{gate}}" != "flake-shake" ]] && echo --exclude-gates flake-shake ) \
        --log.level debug



clean:
    kurtosis clean --all
    rm -rf tests/interop/loadtest/artifacts


# Build, vet, lint and test Go code in ./cmd
cmd-check:
    #!/usr/bin/env bash
    set -euo pipefail

    cd {{REPO_ROOT}}/op-acceptance-tests

    echo "Downloading Go modules..."
    go mod download

    echo "Building ./cmd/..."
    go build ./cmd/...

    echo "Running go vet on ./cmd/..."
    go vet ./cmd/...

    echo "Running unit tests for ./cmd/..."
    go test -v ./cmd/...
